home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / netBoot.new / dev / if_ie.c < prev    next >
C/C++ Source or Header  |  1990-12-19  |  14KB  |  538 lines

  1. #ifndef    M25
  2. #ifndef lint
  3. /* static    char sccsid[] = "@(#)if_ie.c 1.1 86/09/27 Copyr 1986 Sun Micro"; */
  4. #endif
  5.  
  6. /*
  7.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  8.  */
  9.  
  10. /*****************************************************************************
  11.  * 10-Dec-85    RJHG
  12.  *     ADD signal user that we have lost carrier (or couldn't find it).
  13.  *        This usually means that the cable is bad
  14.  *    ADD the word Prom in front of all error messages from this driver
  15.  *        that currently use form 'ie: '. New form 'Prom-ie: '.  This way
  16.  *        the user will know that this is the prom driver having trouble. 
  17.  *  7-Jan-86    RJHG
  18.  *   REMOVE the word Prom in front of all error messages from this driver
  19.  *          at the request of the Project Leader (B. Harris) as we don't 
  20.  *          have control of the sources so these changes will be lost if
  21.  *          the other software group happens to make a change in the driver.
  22.  *          Now that raises the question of what happens to the change adding
  23.  *          the "lost carrier" message.
  24.  *****************************************************************************/
  25.  
  26. /* 
  27.  * Parameters controlling TIMEBOMB action: times out if chip hangs.
  28.  */
  29. #define    TIMEBOMB    1000000        /* One million times around is all... */
  30. #define    TIMEOUT        -1        /* if (function()) return (TIMEOUT); */
  31. #define    OK        0        /* Traditional OK value */
  32.  
  33. /*
  34.  * Sun Intel Ethernet Controller interface
  35.  */
  36. #include "../dev/saio.h"
  37. #include "../h/socket.h"
  38. #include "../dev/if.h"
  39. #include "../h/in.h"
  40. #include "../dev/if_ether.h"
  41. #include "../dev/if_iereg.h"
  42. #include "../dev/if_mie.h"
  43. #include "../dev/if_obie.h"
  44. #include "../h/idprom.h"
  45. #include "../sun3/cpu.map.h"    
  46.  
  47. int   iexmit(), iepoll(), iereset();
  48.  
  49. struct saif ieif = {
  50.     iexmit,
  51.     iepoll,
  52.     iereset,
  53. };
  54.  
  55. #define    IEVVSIZ        1024        /* # of pages in page map */
  56. #define IEPHYMEMSIZ    (8*1024)
  57. #define IEVIRMEMSIZ    (8*1024)
  58. #define IEPAGSIZ    1024
  59. #define    IERBUFSIZ    1600
  60. #define    IEXBUFSIZ    1600
  61. #define    IEDMABASE    0x0F000000    /* Can access top 16MB of memory */
  62.  
  63. /* Location in virtual memory of the SCP (System Configuration Pointer) */
  64. #define SCP_LOC (char *)(IEDMABASE+IESCPADDR)    
  65.  
  66. struct ie_softc {
  67.     char    es_fill[BYTESPERPG-sizeof(struct iescp)];    /* Align @end */
  68.     struct    iescp    es_scp;        /* System config pointer (used once) */
  69.     struct    ieiscp    es_iscp;    /* Intermediate sys config ptr (once) */
  70.     struct    iescb    es_scb;        /* Sys Control Block, the real mama */
  71.     struct    ierbd    es_rbd;
  72.     struct    ierbd    es_rbd2;    /* Hack for 82586 ucode bugs */
  73.     struct    ierfd    es_rfd;
  74.     struct    ietfd    es_tfd;
  75.     struct    ietbd    es_tbd;
  76.     struct    mie_device *es_mie;
  77.     struct    obie_device *es_obie;
  78.     short    es_type;
  79.     struct    ieiaddr    es_iaddr;    /* Cmd to set up our Ethernet addr */
  80.     struct    ieconf    es_ic;        /* Cmd to configure the chip */
  81.     char    es_rbuf[IERBUFSIZ];
  82.     char    es_xbuf[IEXBUFSIZ];    /* Only used in Multibus version */
  83.     char    es_rbuf2[10];        /* Hack for 82586 ucode bugs */
  84. };
  85.  
  86. /*
  87.  * This initializes the onboard Ethernet control reg to:
  88.  *    Reset is active
  89.  *    Loopback is NOT active
  90.  *    Channel Attn is not active
  91.  *    Interrupt enable is not active.
  92.  * Loopback is deactivated due to a bug in the Intel serial interface
  93.  * chip.  This chip powers-up in a locked up state if Loopback is active.
  94.  * It "unlocks" itself if you release Loopback; then it's OK to reassert it.
  95.  */
  96. struct obie_device obie_reset = {0, 1, 0, 0, 0, 0, 0};
  97.  
  98. ieoff_t to_ieoff();
  99. ieaddr_t to_ieaddr();
  100.  
  101. struct devinfo ieinfo = {
  102.     0, sizeof (struct ie_softc), 0, 0, (unsigned long *)0, MAP_OBIO,
  103. };
  104.  
  105. int ieprobe(), tftpboot(), ieopen(), ieclose(), etherstrategy();
  106.  
  107. struct boottab iedriver = {
  108.         "ie",   ieprobe,        tftpboot, ieopen,         ieclose,
  109.         etherstrategy,     "ie: Sun/Intel Ethernet",       &ieinfo,
  110. };
  111.  
  112. /*
  113.  * Probe for device.
  114.  * Must return -1 for failure for monitor probe
  115.  */
  116. ieprobe(sip)
  117.     struct saioreq *sip;
  118. {
  119.     return (0);    /* onboard Ethernet */
  120. }
  121.  
  122. /*
  123.  * Open Intel Ethernet nd connection, return -1 for errors.
  124.  */
  125. ieopen(sip)
  126.     struct saioreq *sip;
  127. {
  128.     register int result;
  129.  
  130.     sip->si_sif = &ieif;
  131.     if ( ieinit(sip) || (result = etheropen(sip)) < 0 ) {
  132.         ieclose(sip);        /* Make sure we kill chip */
  133.         return (-1);
  134.     }
  135.     return (result);
  136. }
  137.  
  138. /*
  139.  * Set up memory maps and Ethernet chip.
  140.  * Returns 1 for error, 0 for ok.
  141.  */
  142. int
  143. ieinit(sip)
  144.     struct saioreq *sip;
  145. {
  146.     register struct ie_softc *es;
  147.     int paddr;
  148.     int i;
  149.     
  150.     register struct obie_device *obie;
  151.  
  152.     es = (struct ie_softc *)sip->si_dmaaddr;
  153.     es->es_obie = obie = (struct obie_device *)
  154.     devalloc(MAP_OBIO, VIOPG_ETHER << BYTES_PG_SHIFT, sizeof(*obie));
  155.     sip->si_devdata = (caddr_t)es;
  156.     return iereset(es, sip);
  157. }
  158.  
  159. /*
  160.  * Basic 82586 initialization
  161.  * Returns 1 for error, 0 for ok.
  162.  */
  163. int
  164. iereset(es, sip)
  165.     register struct ie_softc *es;
  166.     struct saioreq *sip;
  167. {
  168.     struct ieiscp *iscp = &es->es_iscp;
  169.     struct iescb *scb = &es->es_scb;
  170.     struct ieiaddr *iad = &es->es_iaddr;
  171.     struct ieconf *ic = &es->es_ic;
  172.     int i, j;
  173.     register struct mie_device *mie = es->es_mie;
  174.     register struct obie_device *obie = es->es_obie;
  175.     for (j = 0; j < 10; j++) {
  176.         /* Set up the control blocks for initializing the chip */
  177.         bzero((caddr_t)&es->es_scp, sizeof (struct iescp));
  178.         es->es_scp.ie_iscp = to_ieaddr(es, (caddr_t)iscp);
  179.         bzero((caddr_t)iscp, sizeof (struct ieiscp));
  180.         iscp->ie_busy = 1;
  181.         iscp->ie_cbbase = 0;
  182.         iscp->ie_scb = to_ieoff(es, (caddr_t)scb);
  183.         iscp->ie_cbbase = to_ieaddr(es, (caddr_t)es);
  184.         bzero((caddr_t)scb, sizeof (struct iescb));
  185.         /*
  186.          * The 82586 has bugs that require us to be in 
  187.          * loopback mode while we initialize it, to avoid
  188.          * transitions on CRS (carrier sense).
  189.          * 
  190.          * However, the Intel serial interface chip used
  191.          * on Carrera also has bugs: if it powers-up in
  192.          * loopback, you have to release loopback at least
  193.          * once to make it behave -- it powers up with
  194.          * CRS and CDT permanently active, which rapes the 586.
  195.          *
  196.          * How do you spell "broken"?  I-N-T-E-L...
  197.          */
  198.         *obie = obie_reset;    /* Reset chip & interface */
  199.         DELAY(20);
  200.         obie->obie_noloop = 0;    /* Put it in loopback now */
  201.         DELAY(20);
  202.         obie->obie_noreset = 1;    /* Release Reset on 82586 */
  203.         DELAY(200);
  204.         /*
  205.          * Now set up to let the Ethernet chip read the SCP.
  206.          * Intel wired in the address of the SCP.  It happens
  207.          * to be 0xFFFFF6.
  208.          */
  209.         (*(struct iescp *)SCP_LOC) = es->es_scp;
  210.         /*
  211.          * We are set up.  Give the chip a zap, then wait up to
  212.          * 100 msec, or until chip comes ready.
  213.          */
  214.         ieca(es);
  215.         CDELAY(iscp->ie_busy != 1, 100);
  216.  
  217.         if (iscp->ie_busy == 1)      /* If no init, reset chip again. */
  218.             obie->obie_noreset = 0;
  219.         if (iscp->ie_busy == 1)
  220.             continue;    /* Continue loop until we get it */
  221.  
  222.         /*
  223.          * Now try to run a few simple commands before we say "OK".
  224.          */
  225.         bzero((caddr_t)iad, sizeof (struct ieiaddr));
  226.         iad->ieia_cb.ie_cmd = IE_IADDR;
  227.         myetheraddr((struct ether_addr *)iad->ieia_addr);
  228.         if (iesimple(es, &iad->ieia_cb)) {
  229.             printf("ie: hang while setting Ethernet address.\n");
  230.             continue;
  231.         }
  232.  
  233.         iedefaultconf(ic);
  234.         if (iesimple(es, &ic->ieconf_cb)) {
  235.             printf("ie: hang while setting chip config.\n");
  236.             continue;
  237.         }
  238.  
  239.         /*
  240.          * Take the Ethernet interface chip out of loopback mode, i.e.
  241.          * put us on the wire.  We can't do this before having
  242.          * initialized the Ethernet chip because the chip does random
  243.          * things if its 'wire' is active between the time it's reset
  244.          * and the first CA.  Also, the IA-setup and configure commands
  245.          * will hang under some conditions unless the interface is
  246.          * very quiet and still.
  247.          */
  248.         obie->obie_noloop = 1;
  249.         if (ierustart(es)) {
  250.             printf("ie: hang while starting receiver.\n");
  251.             continue;
  252.         }
  253.             
  254.         return 0;        /* It all worked! */
  255.     }
  256.  
  257.     /* We tried a bunch of times, no luck. */
  258.     printf("ie: cannot initialize\n");
  259.     return 1;
  260. }
  261.  
  262. /*
  263.  * Initialize and start the Receive Unit
  264.  */
  265. int
  266. ierustart(es)
  267.     register struct ie_softc *es;
  268. {
  269.     register struct ierbd *rbd = &es->es_rbd;
  270.     struct ierbd *rbd2 = &es->es_rbd2;
  271.     register struct ierfd *rfd = &es->es_rfd;
  272.     register struct iescb *scb = &es->es_scb;
  273.     int timebomb = TIMEBOMB;
  274.  
  275.     /*
  276.      * Stop the RU, since we're sharing buffers with it.
  277.      * Then wait until it has really stopped.
  278.      */
  279.     while (scb->ie_rus == IERUS_READY) {
  280.         while (scb->ie_cmd != 0)    /* XXX */
  281.             if (timebomb-- <= 0) return TIMEOUT;
  282.         scb->ie_cmd = IECMD_RU_ABORT;
  283.         ieca(es);
  284.     }
  285.  
  286.     while (scb->ie_cmd != 0)    /* XXX */
  287.         if (timebomb-- <= 0) return TIMEOUT;
  288.  
  289.     /* Real receive buffer descriptor */
  290.     *(short *)rbd = 0;
  291.     rbd->ierbd_next = to_ieoff(es, (caddr_t)rbd2);        /* Fake */
  292.     rbd->ierbd_el = 0;                    /* Fake */
  293.     rbd->ierbd_buf = to_ieaddr(es, es->es_rbuf);
  294.     rbd->ierbd_sizehi = IERBUFSIZ >> 8;
  295.     rbd->ierbd_sizelo = IERBUFSIZ & 0xFF;
  296.  
  297.     /* Fake receive buffer to avoid chip lockups in B0 mask */
  298.     *(short *)rbd2 = 0;
  299.     rbd2->ierbd_next = -1;        /* unnecessary since el = 1 */
  300.     rbd2->ierbd_el = 1;
  301.     rbd2->ierbd_buf = to_ieaddr(es, es->es_rbuf2);
  302.     rbd2->ierbd_sizehi = 0;
  303.     rbd2->ierbd_sizelo = sizeof(es->es_rbuf2) & 0xFF;
  304.  
  305.     /* Real receive frame descriptor */
  306.     *(short *)rfd = 0;
  307.     rfd->ierfd_next = -1;        /* Unused since el = 1 */
  308.     rfd->ierfd_el = 1;
  309.     rfd->ierfd_susp = 1;        /* Suspend after receiving one */
  310.     rfd->ierfd_rbd = to_ieoff(es, (caddr_t)rbd);
  311.  
  312.     /*
  313.      * Start the RU again.
  314.      */
  315.     scb->ie_rfa = to_ieoff(es, (caddr_t)rfd);
  316.     scb->ie_cmd = IECMD_RU_START;
  317.     ieca(es);
  318.     return OK;
  319. }
  320.  
  321. ieca(es)
  322.     register struct ie_softc *es;
  323. {
  324.     es->es_obie->obie_ca = 1;
  325.     es->es_obie->obie_ca = 0;
  326. }
  327.  
  328. int
  329. iesimple(es, cb)
  330.     register struct ie_softc *es;
  331.     register struct iecb *cb;
  332. {
  333.     register struct iescb *scb = &es->es_scb;
  334.     register timebomb = TIMEBOMB;
  335.  
  336.     *(short *)cb = 0;    /* clear status bits */
  337.     cb->ie_el = 1;
  338.     cb->ie_next = 0;
  339.  
  340.     /* start CU */
  341.     while (scb->ie_cmd != 0)    /* XXX */
  342.         if (timebomb-- <= 0) return TIMEOUT;
  343.     scb->ie_cbl = to_ieoff(es, (caddr_t)cb);
  344.     scb->ie_cmd = IECMD_CU_START;
  345.     if (scb->ie_cx)
  346.         scb->ie_cmd |= IECMD_ACK_CX;
  347.     if (scb->ie_cnr)
  348.         scb->ie_cmd |= IECMD_ACK_CNR;
  349.     ieca(es);
  350.     while (!cb->ie_done)        /* XXX */
  351.         if (timebomb-- <= 0) return TIMEOUT;
  352.     while (scb->ie_cmd != 0)    /* XXX */
  353.         if (timebomb-- <= 0) return TIMEOUT;
  354.     if (scb->ie_cx)
  355.         scb->ie_cmd |= IECMD_ACK_CX;
  356.     if (scb->ie_cnr)
  357.         scb->ie_cmd |= IECMD_ACK_CNR;
  358.     ieca(es);
  359.     return OK;
  360. }
  361.  
  362. /*
  363.  * Transmit a packet.
  364.  * Multibus has to copy the packet onto the board.
  365.  * Onboard just plays it where it lies.
  366.  */
  367. iexmit(es, buf, count)
  368.     register struct ie_softc *es;
  369.     char *buf;
  370.     int count;
  371. {
  372.     register struct ietbd *tbd = &es->es_tbd;
  373.     register struct ietfd *td = &es->es_tfd;
  374.  
  375.     bzero((caddr_t)tbd, sizeof *tbd);
  376.     tbd->ietbd_eof = 1;
  377.     tbd->ietbd_cntlo = count & 0xFF;
  378.     tbd->ietbd_cnthi = count >> 8;
  379.     bcopy(buf, es->es_xbuf, count);
  380.     tbd->ietbd_buf = to_ieaddr(es, es->es_xbuf);
  381.     td->ietfd_tbd = to_ieoff(es, (caddr_t)tbd);
  382.     td->ietfd_cmd = IE_TRANSMIT;
  383.     if (iesimple(es, (struct iecb *)td)) {
  384.         printf("ie: xmit hang\n");
  385.         return -1;
  386.     }
  387. /*****************************************************************************
  388.  * 10-Dec-85    RJHG
  389.  *     ADD signal user that we have lost carrier (or couldn't find it).
  390.  *        This usually means that the cable is bad.
  391.  *
  392.  *****************************************************************************/
  393.     if (td->ietfd_nocarr)
  394.         printf("ie: No Carrier\n"); /* tested here cause the    */
  395.                          /* intel manual was VERY    */
  396.                          /* unclear about this bit   */
  397.                          /* being reflected in the   */
  398.                          /* command successful field */
  399.  
  400.  
  401.     if (td->ietfd_ok)
  402.         return (0);
  403.     if (td->ietfd_xcoll)
  404.         printf("ie: Ethernet cable problem\n");
  405.     return (-1);
  406. }
  407.  
  408.  
  409.  
  410. int
  411. iepoll(es, buf)
  412.     register struct ie_softc *es;
  413.     char *buf;
  414. {
  415.     register struct ierbd *rbd = &es->es_rbd;
  416.     register struct ierfd *rfd = &es->es_rfd;
  417.     register struct iescb *scb = &es->es_scb;
  418.     int len;
  419.     int timebomb = TIMEBOMB;
  420.     
  421.     /*
  422.      * Note, this assumes that the RU is set up to get out of READY
  423.      * state after receiving one packet.
  424.      */
  425.     if (scb->ie_rus == IERUS_READY) {
  426.         return (0);            /* No packet yet */
  427.     } else {
  428.         /* RU not ready, see if because we got a packet. */
  429.         if (!rfd->ierfd_done || !rbd->ierbd_eof) {
  430.             ierustart(es);
  431.             return (0);
  432.         }
  433.     }
  434.  
  435.     /*
  436.      * We got a packet.
  437.      */
  438.     len = (rbd->ierbd_cnthi << 8) + rbd->ierbd_cntlo;
  439.     bcopy(es->es_rbuf, buf, len);
  440.     while (scb->ie_cmd != 0)    /* XXX */
  441.         if (timebomb-- <= 0) return TIMEOUT;
  442.     if (scb->ie_fr)
  443.         scb->ie_cmd |= IECMD_ACK_FR;
  444.     if (scb->ie_rnr)
  445.         scb->ie_cmd |= IECMD_ACK_RNR;
  446.     ieca(es);
  447.     ierustart(es);
  448.     return (len);
  449. }
  450.  
  451. /*
  452.  * Convert a CPU virtual address into an Ethernet virtual address.
  453.  *
  454.  * For Multibus, we assume it's in the Ethernet's memory space, and we
  455.  * just subtract off the start of the memory space (==es).  For Model 50,
  456.  * the Ethernet chip has full access to supervisor virtual memory.
  457.  * For Carrera, the chip can access the top 16MB of virtual memory,
  458.  * but we never give it addresses outside that range, so the high
  459.  * order bits can be ignored.
  460.  */
  461. ieaddr_t
  462. to_ieaddr(es, cp)
  463.     struct ie_softc *es;
  464.     caddr_t cp;
  465. {
  466.     union {
  467.         int    n;
  468.         char    c[4];
  469.     } a, b;
  470.  
  471.     a.n = (int)cp;
  472.     b.c[0] = a.c[3];
  473.     b.c[1] = a.c[2];
  474.     b.c[2] = a.c[1];
  475.     b.c[3] = 0;
  476.     return (b.n);
  477. }
  478.  
  479. /*
  480.  * Convert a CPU virtual address into a 16-bit offset for the Ethernet
  481.  * chip.
  482.  *
  483.  * This is the same for Onboard and Multibus, since the offset is based
  484.  * on the absolute address supplied in the initial system configuration
  485.  * block -- which we customize for Multibus or Onboard.
  486.  */
  487. ieoff_t
  488. to_ieoff(es, addr)
  489.     register struct ie_softc *es;
  490.     caddr_t addr;
  491. {
  492.     union {
  493.         short    s;
  494.         char    c[2];
  495.     } a, b;
  496.  
  497.     a.s = (short)(addr - (caddr_t)es);
  498.     b.c[0] = a.c[1];
  499.     b.c[1] = a.c[0];
  500.     return (b.s);
  501. }
  502.  
  503. /*
  504.  * Set default configuration parameters
  505.  * As spec'd by Intel, except acloc == 1 for header in data
  506.  */
  507. iedefaultconf(ic)
  508.     register struct ieconf *ic;
  509. {
  510.     bzero((caddr_t)ic, sizeof (struct ieconf));
  511.     ic->ieconf_cb.ie_cmd = IE_CONFIG;
  512.     ic->ieconf_bytes = 12;
  513.     ic->ieconf_fifolim = 8;
  514.     ic->ieconf_pream = 2;        /* 8 byte preamble */
  515.     ic->ieconf_alen = 6;
  516.     ic->ieconf_acloc = 1;
  517.     ic->ieconf_space = 96;
  518.     ic->ieconf_slttmh = 512 >> 8;
  519.     ic->ieconf_minfrm = 64;
  520.     ic->ieconf_retry = 15;
  521. }
  522.  
  523. /*
  524.  * Close down intel ethernet device.
  525.  * On the Model 50, we reset the chip and take it off the wire, since
  526.  * it is sharing main memory with us (occasionally reading and writing),
  527.  * and most programs don't know how to deal with that -- they just assume
  528.  * that main memory is theirs to play with.
  529.  */
  530. ieclose(sip)
  531.     struct saioreq *sip;
  532. {
  533.     register struct ie_softc *es = (struct ie_softc *) sip->si_devdata;
  534.  
  535.     *es->es_obie = obie_reset;
  536. }
  537. #endif    M25
  538.